牛客周赛 Round35
A 小红的字符串切割
小红拿到了一个长度为偶数的字符串,请你将其切割成长度相等的两部分并输出。
void solve() {
string s;cin >> s;
for (int i = 0;i < s.size() / 2;i++) {
cout << s[i];
}
cout << '\n';
for (int i = s.size() / 2;i < s.size();i++) {
cout << s[i];
}
}
B 小红的数组分配
小红拿到了一个长度为
还可以直接用 map
看是否有不等于 2 的,有则无解
void solve() {
int n;cin >> n;vector<int> a(2 * n + 1);for (int i = 1;i <= 2 * n;i++)cin >> a[i];
sort(a.begin() + 1, a.begin() + 1 + 2 * n);
vector<int> p1, p2;
for (int i = 1;i <= 2 * n;i++) {
if (i % 2) {
p1.push_back(a[i]);
} else {
p2.push_back(a[i]);
}
}
for (int i = 0;i < n;i++) {
if (p1[i] != p2[i]) {
cout << "-1\n";return;
}
}
for (auto i : p1)cout << i << ' ';
cout << '\n';
for (auto i : p2)cout << i << ' ';
cout << '\n';
}
C 小红关鸡
有
void solve() {
int n, k;cin >> n >> k;vector<int> a(n);for (auto& i : a)cin >> i;
sort(a.begin(), a.end());
int ans = 0;
for (int i = 0;i < n;i++) {
int t = a[i] + k;
int res = upper_bound(a.begin(), a.end(), t) - a.begin() - i;
ans = max(ans, res);
}
cout << ans * 1.0 / n << '\n';
}
还可以双指针操作只需要
sort(a);
int l = 0, r = 0, ans = 0;
while (r < n) {
while (a[r] - a[l] > k)l++;
ans = max(ans, r - l + 1);
r++;
}
cout << ans * 1.0 / n << '\n';
D 小红的排列构造
小红得到了一个数组,她想尽量少地修改元素,使其成为一个排列。你能帮帮她吗?
void solve() {
int n;cin >> n;vector<int> a(n + 1), b, c;
map<int, int> m;
for (int i = 1;i <= n;i++) {
cin >> a[i];
m[a[i]]++;
}
int ans = 0;
for (int i = 1;i <= n;i++) {
if (m[i] == 0) {
ans++;c.push_back(i);
}
if (a[i] > n || (a[i] <= n && m[a[i]] > 1)) {
b.push_back(i);m[a[i]]--;
}
}
cout << ans << '\n';
for (int i = 0;i < ans;i++) {
cout << b[i] << " " << c[i] << '\n';
}
}
E 小红的无向图构造
小红希望你构造一个无向连通图,满足共有
Sloution
构造
先将必须连接的连接了,再连接不影响最短路长度的路径直到
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
void solve() {
int n, m;cin >> n >> m;
vector<int> a(n + 1), g[n + 1];
for (int i = 1;i <= n;i++) {
cin >> a[i];
g[a[i]].push_back(i);
}
if (m < n - 1) {
cout << "-1\n";return;
}
vector<pair<int, int>>ans;
int maxa = *(max_element(a.begin() + 1, a.begin() + 1 + n));
for (int i = 1;i <= maxa;i++) {
if (g[i].empty()) {
cout << "-1\n";return;
}
for (auto j : g[i])ans.push_back({g[i - 1][0], j});
}
if (ans.size() < m) {
for (int i = 1;i <= maxa;i++) {
for (int j = 0;j < g[i].size();j++) {
for (int k = j + 1;k < g[i].size();k++) {
ans.push_back({g[i][j],g[i][k]});
if (ans.size() == m)goto next;
}
}
}
for (int i = 1;i <= maxa;i++) {
for (int j = 1;j < g[i].size();j++) {
for (auto k : g[i + 1]) {
ans.push_back({g[i][j], k});
if (ans.size() == m)goto next;
}
}
}
}
if (ans.size() < m) {
cout << "-1\n";return;
}
next:
for (auto [i, j] : ans) {
cout << i << " " << j << '\n';
}
}
(待更
F/G 小红的子序列权值和
小红定义一个数组的权值为:数组所有元素乘积的因子数量。例如,
的权值为 4。
现在小红拿到了一个数组,她想求出数组中所有非空子序列的权值之和。你能帮帮她吗?由于答案过大,请对
定义数组的子序列为:从左到右选择若干个元素(可以不连续)组成的数组,例如
的子序列有 等。因此,一个大小为 的数组有恰好 个子序列。
Solution
杨辉三角求组合数/逆元/数论
设
void solve() {
int n;cin >> n;
vector<vector<ll>> c(n + 1, vector<ll>(n + 1));
for (int i = 0;i <= n;i++) {
for (int j = 0;j <= i;j++) {
if (j == 0 || j == i)c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
array<int, 4> num = {};
ll t = 1;
for (int i = 1;i <= n;i++) {
int x;cin >> x;
num[x]++;
}
ll ans = 0;
for (int i = 1;i <= num[1];i++) {
t = (2 * t) % mod;
}
for (int i = 0;i <= num[2];i++) {
for (int j = 0;j <= num[3];j++) {
ans += c[num[2]][i] * c[num[3]][j] % mod * (i + 1) % mod * (j + 1) % mod * t % mod;
ans %= mod;
}
}
cout << (ans + mod - 1) % mod << '\n';
}
const int mod = 1e9 + 7;
vector<ll> fact(1e5 + 1);
ll c(int n, int m) {
return fact[n] * (qpow(fact[n - m], mod - 2)) % mod * (qpow(fact[m], mod - 2)) % mod;
}
void solve() {
int n;cin >> n;
fact[0] = 1;
for (int i = 1;i <= n;i++)fact[i] = fact[i - 1] * i % mod;
array<int, 4> num = {};
for (int i = 0;i < n;i++) {
int x;cin >> x;num[x]++;
}
ll t = qpow(2, num[1]);
ll ans = 0, c2 = 0, c3 = 0;
for (int i = 0;i <= num[2];i++) {
c2 += c(num[2], i) * (i + 1) % mod;
c2 %= mod;
}
for (int i = 0;i <= num[3];i++) {
c3 += c(num[3], i) * (i + 1) % mod;
c3 %= mod;
}
cout << (c2 % mod * c3 % mod * t % mod - 1 + mod) % mod << '\n';
}